home *** CD-ROM | disk | FTP | other *** search
- #ifndef WVecIncluded
- #define WVecIncluded
-
- // copyright (c) 1992, 1993 by Paul Wheaton
- // 1916 Brooks #205, Missoula, MT 59801
- //
- // phone: (406)543-1928
- // CompuServe: 72707,207
- // Internet: 72707.207@CompuServe.com
-
- /* things to add
- lower bounds (in an inherited class)
- Minimize() member function to make Alloc==Len
- virtual memory handler (using disk)
- ExtraAlloc() mem func to set how much extra is to be allocated each
- time more memory is allocated (this will speed up rapidly growing
- vectors)
- vector sizes beyond 64k
- */
-
- #include <WMisc.h>
-
- #ifdef MAJORBBS
- #include <stdlib.h>
- #endif
-
- class File;
-
- typedef const void* ConstVoidPointerType; // xxx used to clear up cfront prob
-
- class ByteVector
- {
- Byte huge* P; // pointer to first Byte in storage
- long Len; // Length of vector
- long Alloc; // amount of actual storage allocated
- long Extra; // amount of extra memory to allocate when getting more memory
- void ReNew(long NewCapacity);
- Byte huge & Ref(long Index);
- friend class BitVector;
- void Assign(const ByteVector& BV);
- void FreeMemory(); // equivalent to new or delete
- Byte Selectors(); // 16M only: number of selectors used. 0 if using malloc
- friend void DebugDisp(const ByteVector& BV);
- friend class File;
- friend class RecFile;
- friend class ObjVec;
- public:
- ByteVector();
- ByteVector(int); // although these say "int", they'll be
- ByteVector(int,int); // converted to Bytes. "int" makes for shorter
- ByteVector(int,int,int); // mangled identifiers than "Byte"
- ByteVector(int,int,int,int);
- ByteVector(int,int,int,int,int);
- ByteVector(int,int,int,int,int,int);
- ByteVector(int,int,int,int,int,int,int);
- ByteVector(int,int,int,int,int,int,int,int);
- ByteVector(int,int,int,int,int,int,int,int,int);
- // see the notes on the constructors at the end of this file
- ByteVector(void* B, long Len); // copy from some pointer
- ByteVector(const ByteVector&);
- ByteVector(File& F); // read a ByteVector object from a file
- ~ByteVector(){FreeMemory();}
- void ExtraAlloc(long Quan){Extra=Quan;}
- // each time more memory is needed, this is how much extra is allocated
- Byte huge & operator[](long Index){return Ref(Index);}
- // To access and modify specific bytes of the vector.
- // Accessing beyond the current length will increase the vector size.
- // Completely range protected.
- void operator=(const ByteVector& BV) {Assign(BV);}
- Bool operator==(const ByteVector& S);
- Bool operator!=(const ByteVector& S) { return !(*this==S); }
- // vector concatenation
- ByteVector operator+(const ByteVector& B);
- ByteVector operator+(Byte B);
- friend ByteVector operator+(Byte B, const ByteVector& BV);
- void operator+=(const ByteVector&);
- void operator+=(Byte B) {Ref(Len)=B;}
- operator ConstVoidPointerType(){return P;}
- void CopyTo(void* Dest, long Bytes=MaxSLong); // copy from vector to memory
- void CopyFrom(void* Source, long Bytes); // copy from memory to vector
- //friend void operator=(void* Dest,const ByteVector& BV) {BV.CopyTo(Dest);}
- void WriteTo(File& F); // write a ByteVector object to file
- long Capacity() {return Alloc;}
- long ReAlloc(long NewCapacity);
- void MinimizeMemory();
- // reduce memory consumption to just what is needed now
- long Size() {return Len;}
- long Index(Byte SearchByte, long StartIndex=0);
- // returns the const NotFound if the Byte is not found in the vector
- // otherwise returns the index
-
- Byte operator()(long Index); // return an indexed byte.
- ByteVector operator()(long Index, long Length); // return a subvector
- Byte At(long I);
- ByteVector At(long Index, long Length);
- ByteVector Before(long Index) {return At(0,Index);}
- ByteVector Through(long Index) {return At(0,Index+1);}
- ByteVector From(long Index);
- ByteVector After(long Index);
- void Insert(Byte C,long Index=0);
- void Insert(const ByteVector& BV,long Index=0);
- void Delete(long Index=0,long Length=1);
- void Clear(Byte B=0); // set all elements to B
- void ClearFirst(long Quan) {Ref(Quan); Clear();}
- // great for initializing a vector
- long Sum();
- void Empty(){Len=0;}
- void Clip(long NewSize);
- #ifdef MAJORBBS
- void* operator new(size_t size){return malloc(size);}
- void operator delete(void* p) {free(p);}
- #endif
- };
-
- extern Bool BigVectorJump;
- /* If true, then vectors in size >64k will always be allocated in chunks of
- 64k. This saves on fragmentation and recopying time. Default is True. */
-
- const DefaultVectorExtra=16;
-
- /*
-
- ByteVector constructors:
-
- I wanted to use a variable argument constructor (see your favorite texts
- on "elipsis", "...", "variable arguments" or "va_arg, va_end and
- va_start") but there were limitations that I felt could lead to very hard
- to find bugs, namely that the applications programmer must first pass a
- value that reveals how many parameters there are. Being off by one could
- lead to a variety of problems.
-
- There are four ways to construct a ByteVector:
-
- 1) ByteVector BV;
-
- This creates a vector that will have a length of 0 although some
- memory will be allocated so that elements may be added later (which
- is the most likely thing to happen).
-
- 2) ByteVector BV(1,2,55,8);
-
- This creates a vector of length 4. You may pass 1 to 9 parameters
- using this type of constructors. You're limited to 9 because the
- Glock C++ name mangling mixed with MSC 5.1 limits it this way. An
- update of either of these may solve this problem.
-
- 3) static Byte BA[]={1,2,55,8};
- ByteVector BV(BA,4);
-
- This creates a vector of length 4, copying the elements from BA.
- You don't have to copy from an array of bytes, you can use any kind
- of array or even a pointer to anywhere in memory.
-
- 4) ByteVector BV2(BV);
-
- Create a ByteVector from another ByteVector.
-
- */
-
- /*
-
- Note that I use the word "Atomic" in the context that it's used in the
- LISP language, meaning language primitives such as int, long and float.
-
- The classes that are derived from ObjVec using the macros
- "CreateAtomicVectorClass" or "CreateRefVectorClass"are for those types of
- objects that do not need any special class constructors or destructors.
- The former macro passes values through the stack as much as possible.
- The latter passes pointers (as references). They should both appear to
- work the same way although there may be some differences in time and
- space usage depending on your object size and how you use your vectors.
-
- Again, do not use objects in these vectors that cannot be bit copied,
- such as class objects that contain pointers that require stack
- maintenance.
-
- */
-
- typedef int (* CompFuncPtr)(const void*,const void*);
-
- class ObjVec: private ByteVector
- {
- int ObjSize; // size of struct or atomic object: 2 if int, 4 if long, etc.
- int BlockSize; // see "BlockSize" at bottom of file
- CompFuncPtr CFP;
- void CtorHelper(int);
- CompFuncPtr CurCompFunc() const;
- public:
- ObjVec(int ObjectSize);
- ObjVec(int ObjectSize,void*);
- ObjVec(int ObjectSize,void*,void*);
- ObjVec(int ObjectSize,void*,void*,void*);
- ObjVec(int ObjectSize,void* P, long Len); // copy from some pointer
- ObjVec(const ObjVec&);
-
- void ExtraAlloc(long Quan);
- // when more memory is needed, how much more memory should be allocated?
- void* Ref(long Index); // returns pointer to that element
- operator ConstVoidPointerType() const; //{return P;}
- void CopyTo(void* Dest, long Quan=MaxSLong) const; // copy from vector to memory
- void CopyFrom(void* Source, long Quan); // copy to vector from memory
- void WriteTo(File&) const; // write a ObjVec object to file
- long Capacity() const; // {return (Alloc/ObjSize);}
- long ByteCapacity() const;
- long ReAlloc(long NewCapacity);
- long Size() const; // {return Len/ObjSize);}
- //friend void operator=(void* Dest,const ObjVec& V);
- void operator=(const ObjVec& V);// {Assign(V);}
- //Bool operator==(ObjVec&);
- //Bool operator!=(ObjVec& V);// { return !(*this==V); }
- long Index(void* SearchObj, long StartIndex) const;
- void operator+=(const ObjVec&);
- ObjVec Concat(const ObjVec&) const;
- ObjVec Concat(void*) const;
- void AppendOneObj(void*);
- ObjVec PrependOneObj(void*) const; // does not modify current obj
- void Insert(const ObjVec& V,long Index=0);
- void Insert(void*,long Index);
- void Delete(long Index=0,long Length=1);
- void Pop(){Delete(Size()-1,1);}
- //void Clear(int X=0); // set all elements to X
- void ClearFirst(long Quan) {Ref(Quan); Clear();}
- // great for initializing a vector
- long Sum() const;
- void Empty(); //{Len=0;}
- ObjVec At(long,long) const;
- void* At(long) const;
- ObjVec From(long index) const;
- ObjVec After(long index) const;
- void Clip(long NewSize){ByteVector::Clip(NewSize*BlockSize);}
-
- void SetCompFunction(void* F){CFP=(CompFuncPtr)F;}
- // in BInsert(), FindE() and FindGE(), this function will be used in
- // the binary search. memcmp() will be used if this function not called
- long BInsert(void* X);
- // does a binary search and then inserts X. returns index num. if a
- // dupe is found, nothing is inserted and the match index is returned.
- long FindE(void* SearchObj) const;
- // binary search. returns index. returns NotFound if no exact match
- long FindGE(void* SearchObj) const;
- // returns NotFound if SearchObj is greater than last element
- void QSort();
-
- #ifdef MAJORBBS
- void* operator new(size_t size){return malloc(size);}
- void operator delete(void* p) {free(p);}
- #endif
- };
-
- #define CreateAtomicVectorClass(ClassName,ObjType) \
- typedef int (* ObjType ## CompFuncPtr)(const ObjType*,const ObjType*); \
- class ClassName:public ObjVec \
- { \
- public: \
- ClassName():ObjVec(sizeof(ObjType)){} \
- ClassName(ObjType X):ObjVec(sizeof(ObjType),&X){} \
- ClassName(ObjType X1, ObjType X2):ObjVec(sizeof(ObjType),&X1,&X2){} \
- ClassName(ObjType X1, ObjType X2, ObjType X3) \
- :ObjVec(sizeof(ObjType),&X1,&X2,&X3){} \
- ClassName(void* P, long Len):ObjVec(sizeof(ObjType),P,Len){} \
- ClassName(const ClassName& V):ObjVec(V){} \
- ClassName(const ObjVec& V):ObjVec(V){} \
- ObjType& Ref(long Index) {return *(ObjType*)ObjVec::Ref(Index);} \
- ObjType& operator[](long Index){return *(ObjType*)ObjVec::Ref(Index);} \
- void operator+=(ObjType X){AppendOneObj(&X);} \
- void operator+=(ClassName X){ObjVec::operator+=(X);} \
- ClassName operator+(const ClassName& V){return ObjVec::Concat(V);} \
- ClassName operator+(ObjType X){return ObjVec::Concat(&X);} \
- friend ClassName operator+(ObjType X, const ClassName& V1) \
- {return V1.PrependOneObj(&X);} \
- long Index(ObjType SearchObj, long StartIndex=0) const \
- {return ObjVec::Index(&SearchObj,StartIndex);} \
- ObjType operator()(long Index) const \
- {return *(ObjType*)ObjVec::At(Index);} \
- ClassName operator()(long Index, long Length) const \
- {return ObjVec::At(Index,Length);} \
- ObjType At(long Index){return *(ObjType*)ObjVec::At(Index);} \
- ClassName At(long Index, long Length) \
- {return ObjVec::At(Index,Length);} \
- ClassName Before(long Index){return ObjVec::At(0,Index);} \
- ClassName Through(long Index){return ObjVec::At(0,Index+1);} \
- ClassName From(long Index){return ObjVec::From(Index);} \
- ClassName After(long Index){return ObjVec::After(Index);} \
- void Insert(ObjType C,long Index=0){ObjVec::Insert(&C,Index);} \
- void SetCompFunction(ObjType ## CompFuncPtr CFP) \
- {ObjVec::SetCompFunction((void*)CFP);} \
- long BInsert(ObjType X){return ObjVec::BInsert(&X);} \
- long FindE(ObjType X){return ObjVec::FindE(&X);} \
- long FindGE(ObjType X){return ObjVec::FindGE(&X);} \
- };
-
- #define CreateRefVectorClass(ClassName,ObjType) \
- typedef int (* ObjType ## CompFuncPtr)(const ObjType*,const ObjType*); \
- class ClassName:public ObjVec \
- { \
- public: \
- ClassName():ObjVec(sizeof(ObjType)){} \
- ClassName(ObjType& X):ObjVec(sizeof(ObjType),&X){} \
- ClassName(ObjType& X1, ObjType& X2): \
- ObjVec(sizeof(ObjType),&X1,&X2){} \
- ClassName(ObjType& X1, ObjType& X2, ObjType& X3) \
- :ObjVec(sizeof(ObjType),&X1,&X2,&X3){} \
- ClassName(void* P, long Len):ObjVec(sizeof(ObjType),P,Len){} \
- ClassName(const ClassName& V):ObjVec(V){} \
- ClassName(const ObjVec& V):ObjVec(V){} \
- ObjType& Ref(long Index) {return *(ObjType*)ObjVec::Ref(Index);} \
- ObjType& operator[](long Index){return Ref(Index);} \
- void operator+=(ObjType& X){AppendOneObj(&X);} \
- void operator+=(ClassName X){ObjVec::operator+=(X);} \
- ClassName operator+(const ClassName& V){return Concat(V);} \
- ClassName operator+(ObjType& X){return Concat(&X);} \
- friend ClassName operator+(ObjType& X, const ClassName& V1) \
- {return V1.PrependOneObj(&X);} \
- long Index(ObjType& SearchObj, long StartIndex=0) \
- {return ObjVec::Index(&SearchObj,StartIndex);} \
- ObjType operator()(long Index) {return *(ObjType*)ObjVec::At(Index);} \
- ClassName operator()(long Index, long Length) \
- {return ObjVec::At(Index,Length);} \
- ObjType At(long Index){return *(ObjType*)ObjVec::At(Index);} \
- ClassName At(long Index, long Length) \
- {return ObjVec::At(Index,Length);} \
- ClassName Before(long Index){return ObjVec::At(0,Index);} \
- ClassName Through(long Index){return ObjVec::At(0,Index+1);} \
- ClassName From(long Index){return ObjVec::From(Index);} \
- ClassName After(long Index){return ObjVec::After(Index);} \
- void Insert(ObjType& C,long Index=0){ObjVec::Insert(&C,Index);} \
- void SetCompFunction(ObjType ## CompFuncPtr CFP) \
- {ObjVec::SetCompFunction((void*)CFP);} \
- long BInsert(ObjType& X){return ObjVec::BInsert(&X);} \
- long FindE(ObjType& X){return ObjVec::FindE(&X);} \
- long FindGE(ObjType& X){return ObjVec::FindGE(&X);} \
- };
-
- /*
-
- BlockSize
-
- In protected mode (16M uses this) when using large chunks of memory
- (beyond 64K), that represent an array of objects, the objects must occupy
- a space that has a size that is a power of two (1, 2, 4, 8, 16, etc.).
- This is so that a long will not lie on a 64k boundry and assignments will
- be done to it (memory is not contiguous but, rather, in 64k chunks
- managed by a table of contiguous pointers).
-
-
- */
-
- CreateAtomicVectorClass(IntVector,int);
- CreateAtomicVectorClass(LongVector,long);
- CreateAtomicVectorClass(CSVector,CharStar);
-
- #endif
-
-